package com.demo.api.service.menu.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.demo.api.cache.MenuCache;
import com.demo.api.interceptor.user.AuthUserInfo;
import com.demo.api.interceptor.user.UserInfo;
import com.demo.client.mapper.user.SysMenuMapper;
import com.demo.client.mapper.user.SysRoleMenuMapper;
import com.demo.api.service.menu.IMenuService;
import com.demo.api.vo.user.MenuVo;
import com.demo.client.model.user.SysMenu;
import com.demo.client.model.user.SysRoleMenu;
import com.demo.client.model.user.SysUser;
import com.demo.core.enums.RedisCacheEnum;
import com.demo.core.redis.RedisCache;
import com.demo.core.redis.RedisTableCache;
import com.demo.core.utils.StringUtils;
import com.demo.core.verification.ValidatorTools;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author Tan-Bowen
 * @version 1.0
 * @description TODO
 * @date 2021/8/28 17:11
 */
@Slf4j
@Service
public class MenuServiceImpl implements IMenuService {

    @Resource
    private SysMenuMapper menuMapper;
    @Resource
    private RedisTableCache redisTableCache;

    @Resource
    private MenuCache menuCache;

    @Resource
    private SysRoleMenuMapper roleMenuMapper;

    @Resource
    private RedisCache redisCache;


    @Override
    public IPage<MenuVo.PageList> pageList(Page<SysMenu> page, MenuVo.Select select) {
        UserInfo userInfo = AuthUserInfo.getUser();
        ValidatorTools.commonThrow(!ValidatorTools.isSuper(userInfo.getDeptId()), "抱歉，您没有该功能权限");
        LambdaQueryWrapper<SysMenu> query = new LambdaQueryWrapper<>();
        query.and(select.getPid() != null,wrapper -> wrapper.eq(SysMenu::getId, select.getPid()).or().eq(SysMenu::getPid, select.getPid()));
        query.eq(select.getType() != null, SysMenu::getType, select.getType());
        query.like(StringUtils.isNotBlank(select.getUrl()), SysMenu::getUrl, select.getUrl());
        query.orderByAsc(SysMenu::getSort);
        IPage<MenuVo.PageList> menus = menuMapper.selectPage(page, query).convert(menu -> BeanUtil.copyProperties(menu, MenuVo.PageList.class));
        menus.getRecords().forEach(item -> {
            SysUser user = redisTableCache.get(SysUser.class, item.getCreateUser());
            if (user != null) {
                item.setCreateName(user.getUserName());
            }
        });
        return menus;
    }


    @Override
    public void create(MenuVo.Create create){
        UserInfo user = AuthUserInfo.getUser();
        create.setCreateUser(user.getUserId());
        SysMenu menu = BeanUtil.copyProperties(create,SysMenu.class);
        ValidatorTools.checkSqlSuccess(menuMapper.insert(menu),"新增菜单失败");
        menuCache.sendRefreshEvent(); //刷新菜单
    }

    @Override
    public void update(MenuVo.Update update){
        SysMenu menu = BeanUtil.copyProperties(update,SysMenu.class);
        ValidatorTools.checkSqlSuccess(menuMapper.updateById(menu),"编辑菜单失败");
        redisTableCache.remove(SysMenu.class,update.getId());
        menuCache.sendRefreshEvent(); //刷新菜单
    }

    @Override
    public List<MenuVo.PageList> getMenuList(){
        List<SysMenu> menus = menuCache.all();
        UserInfo userInfo = AuthUserInfo.getUser();
        ValidatorTools.commonThrow(!ValidatorTools.isSuper(userInfo.getDeptId()), "抱歉，您没有该功能权限");
        return  menus.stream().map(menu->BeanUtil.copyProperties(menu,MenuVo.PageList.class)).collect(Collectors.toList());
    }


    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void deleteMenu(Long menuId){
        SysMenu menu = redisTableCache.get(SysMenu.class,menuId);
        ValidatorTools.commonThrow(menu==null,"菜单不存在");
        // 获取到所有子级菜单
        List<Long> menus = menuCache.getAllDownMenu(menuId).stream().map(SysMenu::getId).collect(Collectors.toList());
        menus.add(menuId);
        // 删除关联关系
        roleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getMenuId,menus));
        Set<Long> roleIds = roleMenuMapper.selectList(new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getMenuId,menus)).stream().map(SysRoleMenu::getRoleId).collect(Collectors.toSet());
        roleIds.forEach(e->{
            redisCache.del(RedisCacheEnum.ROLE_MENU.createKey(e));
        });
        menus.forEach(m->{
            ValidatorTools.checkSqlSuccess(menuMapper.deleteById(m),"删除菜单失败");
            redisTableCache.remove(SysMenu.class,m);
        });
        // 刷新内存中菜单信息
        menuCache.sendRefreshEvent();

    }


}
